OAuth 2.0 的全名為 The OAuth 2.0 Authorization Framework,它是 IETF 所定義的公開標準 RFC 6749 文件裡,裡面定義了授權流程裡,每個角色的任務、授權流程以及傳輪內容的格式等。
文件一開頭的簡介,說明了這個授權框架要解決的問題為何:傳統的 Client-Server 認證模型中,客戶端如果要取得伺服器上被保護的資源(protected resource),那就會需要資源擁有者(resource owner)的憑證(credentials);如果第三方應用程式(third-party applications,後續將簡稱應用程式)需要取得這些資源,勢必要跟資源擁有者共用同一份憑證。
事實上,這個看似合理的做法,裡面有很多安全上的問題:
這場景是不是似曾相識呢?先來看看下面的故事:
Nathan 剛接手一個新創團隊的產品開發,團隊成員都是來自不同領域的高手,每個都期待市場研究員 James 趕快把產品規劃出來,打算創造出能改變產業的獨角獸。
這時,前端轉全端的工程師 Mandy 提出建議:「不然,我們就先來開個 GitHub 版本庫(Repository)吧!總是要有個開始!」大家也都附和這個建議,於是就推舉最年輕又愛烘焙咖啡的 Kevin 來幫大家起個頭。
Kevin 是第一次使用 GitHub,於是就使用個人 email 註冊新帳號,並建立新的版本庫。但突然 Kevin 發現不大對,因為大家如果要有存取與管理版本庫的權限,Kevin 勢必要把自己的帳號密碼提供給其他團隊成員才能有這些權限,但 Kevin 又不想讓其他人知道他的帳號密碼,於是他就突然停下來看著螢幕發呆。資安專家同時又熟悉 GitHub 操作的 Sharon 見狀就上前了解狀況,並跟 Kevin 說明目前授權上所遇到的問題,以及如何在 GitHub 上做多人協作的授權配置方法:
「如果我們透過分享帳號密碼的方法,來達到授權的目的,那就會有帳號擁有者不願意分享帳號密碼的問題。就算帳號擁有者願意,而且大家也都願意使用相同的帳號密碼上傳程式碼,接下來的問題會是,如果有位同仁調部門或是離職,我們就會很難單獨把他的權限收回,唯一的辦法就是修改密碼,然後通知部門內所有人同步換新的密碼。另外,每個人的權限也無法依身分或工作內容做權限控管,因為給了帳密就等於權限全開放。」
「Sharon 你說的沒錯,真的會有這些問題」Kevin 想了想,點點頭回答。
「可是,那我該怎麼做會比較好?」
「GitHub 有提供 Organization 的功能,讓我們可以透過加入帳號的方法來為個別使用者開權限,而不需要提供擁有全部權限的個人帳號與密碼。另外,每個人的權限也都可以個別調整,非常地方便哦!」Sharon 簡短說明了 GitHub 的使用方法與注意事項。
「原來有這麼方便的功能,感覺很有趣,後面就交給我來試試看吧!」Kevin 聽完說明後,就迫不及待地衝刺去準備團隊的版本庫了。
故事中,Kevin 想要把自己放在 GitHub 上的版本庫存取權限,授予給團隊成員,雖然一樣是授權的問題,但這跟 OAuth 2.0 所描述的情境是不同的。在故事裡,Kevin 是資源擁有者的角色,版本庫的權限由 Kevin 管理;團隊成員是請求授權的角色,與 OAuth 2.0 的「應用程式」是類似。而管理授權和存放資源的伺服器,則一樣都是 GitHub。
從這些角色的對應可以發現 Sharon 提到的解法--RBAC(GitHub Organization 管理成員權限的方法是 RBAC),不能完全解決 OAuth 2.0 遇到的情境。原因是 GitHub Organization 操作授權的流程裡,主要操作的產品只有一個--GitHub。有些情境下,可能管理授權和管理資源會是兩個不同的伺服器,但這兩個伺服器的功能通常都是為了同一個產品所開發的,因此原則上還是算同一個產品。
那什麼情境下,產品會不只一個呢?繼續來看下一段故事:
Kevin 完成了版本庫建置之後,也成功地使用了 GitHub 提供的 Organization 功能將團隊成員加入權限,接著就開始建置專案的原始程式碼架構。很快地,大家發現一個問題--持續整合流程想加入第三方源碼檢查服務來增加程式碼品質,但是這個源碼檢查工具會需要讀取 Kevin 所建置的版本庫,因此又遇到跟一開始一樣的問題--需要授權第三方服務存取 Kevin 放在 GitHub 上的原始碼。
因為前一次的經驗,Kevin 決定直接請教 Sharon 這個問題。Sharon 身為資安專家,當然知道這個情境該怎麼解決:
「我們可以找一個有支援 GitHub OAuth 2.0 授權功能的第三方服務,因為 OAuth 2.0 可以在不給予第三方服務密碼的前提下,授與你想給該服務指定的權限,不但安全,彈性也非常高。」
上面這個故事,Kevin 打算將某個特定資源,如 GitHub 上的版本庫,授權給另外一個產品存取。在授權過程需要接觸的產品會有兩個,一個是 GitHub,另一個是第三方源碼檢查服務。而這次需要 GitHub 存取權限的不是使用者,而是一個服務或產品。
這個情境就是 OAuth 2.0 要解決的問題,明天將會來說明 OAuth 2.0 授權流程要如何解決這個問題的。